import * as path from 'path';
import * as vscode from "vscode";
import * as fs from 'fs';
export class CurdService {
    public static storagePath: string;
    public static img = ['cover','img','images','thumb','litpic','image_id','logo','avatar','ico'];
    public static  CreateFile(field,table,type,template='') {
        let fsPath          = vscode.workspace.workspaceFolders.map(item => item.uri.fsPath);
        var arr             = (fsPath[0]).toString().split("\\");
        this.storagePath    = arr.join("/");
        let name            = this.humpName(table);
        let view            = this.viewName(table);
        this.CreateModel(this.storagePath,field,name);
        this.CreateController(this.storagePath,field,name);
        this.CreateHtml(this.storagePath,field,view,name,'add');
        this.CreateHtml(this.storagePath,field,view,name,'edit');
        this.CreateHtml(this.storagePath,field,view,name,'index');
    }
    //创建model
    public static CreateModel(rootPath,field,name) {
        let fileName    =  `/application/common/model/${name}.php`;
        let img         =  this.img;
        let isdel       =  false;//是否有软删除
        let repstr      =  '';//需要替换的值
        let pk          = 'id';
        for (const key in field) {
            var v       = field[key];
            if('isdel'==v['COLUMN_NAME']){
                isdel = true;
            }
            if(-1!=img.indexOf(v['COLUMN_NAME'])){
                repstr += `
            $info['${v.COLUMN_NAME}'] = _sImage($info['${v.COLUMN_NAME}']);`;
            }
            if('PRI'==v['COLUMN_KEY'] && pk!==v['COLUMN_NAME']){ //主键字段
                pk = v['COLUMN_NAME'];
            }
        }
        let content=
`<?php
namespace app\\common\\model;
${isdel?'use think\\model\\concern\\SoftDelete;':''}
use think\\Validate;
class ${name} extends Common
{
    ${isdel?
     `use SoftDelete;
    protected $deleteTime   = 'isdel';`:''}
    protected $autoWriteTimestamp = true;
    protected $createTime = 'ctime';
    protected $updateTime = 'utime';
    ${'id'!=pk?`protected $pk = '${pk}';`:''}
    protected $rule =   [
        'title'         =>  'require',
    ];
    protected $msg  =   [
        'title.require'     =>  '请输入标题名称',
    ];
    public function tableData($post)
    {
        if(isset($post['limit'])){
            $limit      = $post['limit'];
        }else{
            $limit      = config('paginate.list_rows');
        }
        $tableWhere     = $this->tableWhere($post);
        $list           = $this->where($tableWhere['where'])->order($tableWhere['order'])->paginate($limit);
        $data           = $this->tableFormat($list->getCollection());
        $re['code']     = 0;
        $re['msg']      = '';
        $re['count']    = $list->total();
        $re['data']     = $data;
        return $re;
    }
    public function addData($data = [])
    {
        $result = ['status' => true, 'msg' => '保存成功' , 'data' => ''];
        $validate = new Validate($this->rule,$this->msg);
        if(!$validate->check($data))
        {
            $result['status'] = false;
            $result['msg'] = $validate->getError();
        } else {
            if (!$this->allowField(true)->save($data)) {
                $result['status'] = false;
                $result['msg'] = '保存失败';
            }
        }
        return $result;
    }
    public function saveData($data = [])
    {
        $result = ['status' => true, 'msg' => '保存成功', 'data' => ''];
        $validate = new Validate($this->rule, $this->msg);
        if (!$validate->check($data)) {
            $result['status'] = false;
            $result['msg']    = $validate->getError();
        } else {
            if ($this->allowField(true)->save($data, ['id' => $data['id']]) === false) {
                $result['status'] = false;
                $result['msg']    = '保存失败';
            }
        }
        return $result;
    }
    protected function tableWhere($post)
    {
        $where = [];
        if(isset($post['title']) && $post['title'] != ''){
            $where[] = ['title', 'like', '%'.$post['title'].'%'];
        }
        if(isset($post['ctime']) && $post['ctime'] != '') {
            $date_array = explode('~',$post['ctime']);
            $stime = strtotime($date_array[0].'00:00:00',time());
            $etime = strtotime($date_array[1].'23:59:59',time());
            $where[] = ['ctime',['EGT',$stime],['ELT',$etime],'and'];
        }
        $result['where'] = $where;
        $result['field'] = '*';
        $result['order'] = ['${pk}'=>'desc'];
        return $result;
    }
    protected function tableFormat($list)
    {
        foreach($list as $info)
        {
            ${repstr}
        }
        return $list;
    }
    public function getinfo ($id)
    {
        $info = $this->where('${pk}', $id)->find();
        return $info;
    }
}`; 
        this.addFile(fileName,content);
    }
    //创建controller
    public static CreateController(rootPath,field,name) {
        let fileName    = `/application/manage/controller/${name}.php`;
        let content     = 
`<?php
namespace app\\Manage\\controller;
use app\\common\\controller\\Manage;
use app\\common\\model\\${name} as ${name}Model;
use think\\facade\\Request;
class ${name} extends Manage{
    public function index(){
        $model = new ${name}Model();
        if (Request::isAjax()) {
            return $model->tableData(input('param.'));
        }
        return $this->fetch();
    }
    public function add(){
        $this->view->engine->layout(false);
        $model = new ${name}Model();
        if (Request::isPost()) {
            validatezcshopToken();
            return $model->addData(input('param.'));
        }
        return [
            'status' => true,
            'msg'    => '获取成功',
            'data'   => $this->fetch()->getContent()
        ];
    }
    public function edit(){
        $this->view->engine->layout(false);
        $model = new ${name}Model();
        if (Request::isPost()) {
            return $model->saveData(input('param.'));
        }
        $info = $model->where('id', input('param.id/d'))->find();
        if (!$info) {
            return error_code(10002);
        }
        return [
            'status' => true,
            'msg'    => '获取成功',
            'data'   => $this->fetch('edit', ['info' => $info])->getContent()
        ];
    }
    public function del(){
        $result      = ['status' => true, 'msg' => '删除成功', 'data' => ''];
        $model       = new ${name}Model();
        if (!$model->destroy(input('post.id/d'))) {
            $result['status'] = false;
            $result['msg']    = '删除失败';
        }
        return $result;
    }
}`; 
        this.addFile(fileName,content);
    }
    //创建add html
    public static CreateHtml(rootPath,field,view,name,type) {
        let fileName    = `/application/manage/view/${view}/${type}.html`;
        let content;
        switch (type) {
            case 'index':
                content = this.getIndexHtml(field,name,view);
                break;
            case 'add':
                content = this.getAddHtml(field,name,view);
                break;
            case 'edit':
                content = this.getEditHtml(field,name,view);
                break;
        
            default:
                break;
        }
        this.addFile(fileName,content);
    }
    //获取edit.html
    private static getEditHtml(field,name,view){
        let img         = this.img;//图片
        let formdata    = '';
        for (const key in field) {
            var v       = field[key];
            if('isdel'!=v['COLUMN_NAME'] && 'ctime'!=v['COLUMN_NAME'] && 'utime'!=v['COLUMN_NAME']){
                let must = v['IS_NULLABLE']=='NO'?'<i class="required-color">*</i>':'';
                if('PRI'==v['COLUMN_KEY']){
                    formdata +=  `<input type="hidden" name="${v.COLUMN_NAME}" value="{$info.${v.COLUMN_NAME}}">`;
                }else if(v['DATA_TYPE']=='text'){
                    formdata +=  
    `
    <div class="layui-form-item layui-form-text">
        <label class="layui-form-label">${must}${v.COLUMN_COMMENT}：</label>
        <div class="layui-input-block" style="z-index: 1">
            <textarea id="${v.COLUMN_NAME}er" name="${v.COLUMN_NAME}" style="width:100%;height:300px;" type="text/plain" class="layui-textarea">{$info.${v.COLUMN_NAME}}</textarea>
        </div>
    </div>
    <script type="text/javascript">
        var ue = UE.getEditor('${v.COLUMN_NAME}er');
    </script>
                `;

                }else if(-1!=img.indexOf(v['COLUMN_NAME'])){
                    formdata +=  
    `
    <div class="layui-form-item">
        <label class="layui-form-label">${must}${v.COLUMN_COMMENT}：</label>
        <div class="layui-input-inline">
            {Zcspms:image id='${v.COLUMN_NAME}' name='${v.COLUMN_NAME}' value="$info['${v.COLUMN_NAME}']" /}
        </div>
    </div> 
                `;
                }else if('sort'==v['COLUMN_NAME']){
                    formdata +=
    `
    <div class="layui-form-item" style="margin-top: 10px">
        <label class="layui-form-label">排序：</label>
        <div class="layui-input-block">
            <input type="text" name="sort" required lay-verify="required" value="{$info.${v.COLUMN_NAME}}" placeholder="数值越小越靠前" autocomplete="off" class="layui-input">
        </div>
    </div> 
                `;
                }else{
                    formdata +=  
    `
    <div class="layui-form-item">
        <label class="layui-form-label">${must}${v.COLUMN_COMMENT}：</label>
        <div class="layui-input-block">
            <input type="text" name="${v.COLUMN_NAME}" required lay-verify="required" value="{$info.${v.COLUMN_NAME}}" placeholder="请输入${v.COLUMN_COMMENT}" autocomplete="off" class="layui-input">
        </div>
    </div>
                `;
                }
            }
            
        } 
        let content = 
`<div style="padding:30px;" class="layui-form seller-alone-form">
    ${formdata}
    {:zcshopToken()}
    <button class="layui-btn layui-btn-fluid add-save-btn" lay-submit lay-filter="edit-${view}">保存</button>
</div>
<script>
layui.use('form', function(){
    var form = layui.form;
    form.render();
});
</script>`;
        return content;
    }
    //获取add.html
    private static getAddHtml(field,name,view){
        let img         = this.img;//图片
        let formdata    = '';
        console.log(field);
        for (const key in field) {
            var v       = field[key];
            if('PRI'!=v['COLUMN_KEY'] && 'UNI'!=v['COLUMN_KEY'] && 'isdel'!=v['COLUMN_NAME'] && 'ctime'!=v['COLUMN_NAME'] && 'utime'!=v['COLUMN_NAME']){
                let must = v['IS_NULLABLE']=='NO'?'<i class="required-color">*</i>':'';
                if(v['DATA_TYPE']=='text'){
                    formdata +=  
    `
    <div class="layui-form-item layui-form-text">
        <label class="layui-form-label">${must}${v.COLUMN_COMMENT}：</label>
        <div class="layui-input-block" style="z-index: 1">
            <textarea id="${v.COLUMN_NAME}er" name="${v.COLUMN_NAME}" style="width:100%;height:300px;" type="text/plain" class="layui-textarea"></textarea>
        </div>
    </div>
    <script type="text/javascript">
        var ue = UE.getEditor('${v.COLUMN_NAME}er');
    </script>
                `;

                }else if(-1!=img.indexOf(v['COLUMN_NAME'])){
                    formdata +=  
    `
    <div class="layui-form-item">
        <label class="layui-form-label">${must}${v.COLUMN_COMMENT}：</label>
        <div class="layui-input-inline">
            {Zcspms:image id='${v.COLUMN_NAME}' name='${v.COLUMN_NAME}'/}
        </div>
    </div> 
                `;
                }else if('sort'==v['COLUMN_NAME']){
                    formdata +=
    `
    <div class="layui-form-item" style="margin-top: 10px">
        <label class="layui-form-label">排序：</label>
        <div class="layui-input-block">
            <input type="text" name="sort" required lay-verify="required" value="100" placeholder="数值越小越靠前" autocomplete="off" class="layui-input">
        </div>
    </div> 
                `;
                }else{
                    formdata +=  
    `
    <div class="layui-form-item">
        <label class="layui-form-label">${must}${v.COLUMN_COMMENT}：</label>
        <div class="layui-input-block">
            <input type="text" name="${v.COLUMN_NAME}" required lay-verify="required" placeholder="请输入${v.COLUMN_COMMENT}" autocomplete="off" class="layui-input">
        </div>
    </div>
                `;
                }
            }
            
        } 
        let content = 
`<div style="padding:30px;" class="layui-form seller-alone-form">
    ${formdata}
    {:zcshopToken()}
    <button class="layui-btn layui-btn-fluid add-save-btn" lay-submit lay-filter="add-${view}">保存</button>
</div>
<script>
layui.use('form', function(){
    var form = layui.form;
    form.render();
});
</script>`;
        return content;
    }
    //获取index.html  内容
    private static getIndexHtml(field,name,view){
        let img = this.img;//图片
        let tabjs = '';
        for (const key in field) {
            var v       = field[key];
            if(v['DATA_TYPE']!='text' && 'isdel'!=v['COLUMN_NAME']){
                if('PRI'==v['COLUMN_KEY']){
                    tabjs +=  `
            {field: '${v['COLUMN_NAME']}', width:90, title:'ID', align: 'center'},`;
                }else if(-1!=img.indexOf(v['COLUMN_NAME'])){
                    tabjs +=  `
            {field: '${v['COLUMN_NAME']}', width:100,title:'${v.COLUMN_COMMENT}', align: 'center',templet: function(data){
                return '<a href="javascript:void(0);" onclick=viewImage("'+data.${v.COLUMN_NAME}+'")><image style="max-width:30px;max-height:30px;" src="'+data.${v.COLUMN_NAME}+'"/></a>';
            }}, `;
                }else if('sort'==v['COLUMN_NAME']){
                    tabjs +=`
            {field: 'sort', edit: 'text', width:80,title:'排序', align: 'center',templet: function (data) {
                var html = '<a class="link-hot option-show sort" data-id="' + data.sort + '">' + data.sort + '</a>';
                return html;
            }}, `;
                }else{
                    tabjs +=  `
            {field: '${v['COLUMN_NAME']}', width:150,title:'${v.COLUMN_COMMENT}', align: 'center'},`;
                }
            }
            
        }
        let content = 
`<div class="layui-form seller-form"  action="" >
    <div class="layui-form-item">
        <div class="layui-inline">
            <label class="layui-form-label">标题：</label>
            <div class="layui-input-inline seller-inline-4">
                <input type="text" name="title" lay-verify="title" placeholder="请输入搜索关键字" autocomplete="off" class="layui-input">
            </div>
        </div>
        <div class="layui-inline">
            <label class="layui-form-label">更新时间：</label>
            <div class="layui-input-inline seller-inline-4">
                <input type="text" id="date" name="ctime" lay-verify="title" placeholder="开始时间 到 结束时间" autocomplete="off" class="layui-input">
            </div>
        </div>
        <div class="layui-inline">
            <button class="layui-btn layui-btn-sm" lay-submit lay-filter="${view}-search"><i class="iconfont icon-chaxun"></i>筛选</button>
            <button type="button" class="layui-btn layui-btn-sm add-${view}"><i class="layui-icon">&#xe608;</i> 添加</button>
        </div>
    </div>
</div>
<div class="table-body">
    <table id="${view}Table" lay-filter="${view}Table"></table>
</div>
<script>
layui.use(['table','form','laydate'],function(){
    var table = layui.table,form = layui.form,date = layui.laydate;
    table.render({
        elem: '#${view}Table',
        height: 'full-99',
        cellMinWidth: '80',
        url: "{:url('${name}/index')}",
        id: "${view}Table",
        page: true ,
        limit:'20',
        cols: [[${tabjs}
            {field: 'right', title:'操作', width: 140,align:'center', toolbar:'#${view}'}
        ]]
    });
    date.render({
        elem: '#date',
        range: '~',
        trigger: 'click'
    });
    form.on('submit(${view}-search)', function(data){
        layui.table.reload('${view}Table', {
            where: data.field
            ,page: {
                curr: 1
            }
        });
        return false;
    });
    $(document).on('click','.add-${view}',function(){
        JsGet("{:url('${name}/add')}",function (e) {
            if (e.status) {
                window.box = layer.open({
                    type: 1,
                    content: e.data,
                    area: setpage(400,400),
                    title: '添加'
                });
            }else{
                layer.msg(e.msg);
            }
        })
    });
    form.on('submit(add-${view})',function(data){
        JsPost("{:url('${name}/add')}",data.field, function(res){
            if(res.status){
                layer.close(window.box);
                layer.msg(res.msg, {time:1300},function(){
                    table.reload('${view}Table');
                });
            }else{
                layer.msg(res.msg);
            }
        })
    });
    form.on('submit(edit-${view})',function(data){
        JsPost("{:url('${name}/edit')}",data.field, function(res){
            if(res.status){
                layer.close(window.box);
                layer.msg(res.msg, {time:1300},function(){
                    table.reload('${view}Table');
                });
            }else{
                layer.msg(res.msg);
            }
        })
    });
    table.on('tool(${view}Table)', function(obj){
        var data = obj.data;
        var layEvent = obj.event;
        var tr = obj.tr;
        if(layEvent === 'del'){
            layer.confirm('真的要删除吗?', function(index){
                JsPost("{:url('${name}/del')}",{id:data.id},function(res){
                    if(res.status){
                        obj.del();
                        layer.close(index);
                    }
                    layer.msg(res.msg);
                });
            });
        } else if(layEvent === 'edit'){
            JsGet("{:url('${name}/edit')}?id=" + data.id, function(e){
                if (e.status) {
                    window.box = layer.open({
                        type: 1,
                        content: e.data,
                        area: setpage(400,400),
                        title: '修改'
                    })
                }else{
                    layer.msg(e.msg);
                }
            })
        }
    });
})
</script>
<script type="text/html" id="${view}">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>`;
        return content;
    }
    //视图文件夹名称
    private static viewName(str){
        let tabArr  = str.toString().split("_");
        tabArr.shift();
        return tabArr.join("_");
    }
    //驼峰命名
    private static humpName(str){
        let tabArr  = str.toString().split("_");
        let name    = '';
        for (const key in tabArr) {
            if(key!=='0'){ // 第一个默认为 数据库前缀
                name+=tabArr[key].substring(0,1).toUpperCase();
                name+=tabArr[key].substring(1);
            }
        }
        return name;
    }
    //创建文件并写入内容
    private static addFile(fileName,content){
        return new Promise((resolve) => {
            const recordPath = `${this.storagePath}/${fileName}`;
            this.check(path.resolve(recordPath, '..'));
            if (!fs.existsSync(this.storagePath)) {
                fs.mkdirSync(this.storagePath);
            }
            //写入内容
            fs.writeFileSync(recordPath, `${content}`, { encoding: 'utf8' });
            this.editOpenedFileInWindow(recordPath);
            //    文件内追加内容
            //     fs.appendFileSync(recordPath, `${content}`, { encoding: 'utf8' });
            resolve(recordPath)
        });
    }
    private static check(checkPath: string) {

        if (!fs.existsSync(checkPath)) { this.recursiseCreate(checkPath) }

    }
    /**
     * get from StackOverFlow
     * @param folderPath 
     */
    private static recursiseCreate(folderPath: string) {
        folderPath.split(path.sep)
            .reduce((prevPath, folder) => {
                const currentPath = path.join(prevPath, folder, path.sep);
                if (!fs.existsSync(currentPath)) {
                    fs.mkdirSync(currentPath);
                }
                return currentPath;
            }, '');
    }
    //在编辑器打开文件
    private static editOpenedFileInWindow(filePath: string) {
        // 获取 vscode.TextDocument对象
        vscode.workspace.openTextDocument(filePath).then(doc => {
            // 获取 vscode.TextEditor对象
            vscode.window.showTextDocument(doc).then(editor => {
                // 获取 vscode.TextEditorEdit对象， 然后进行字符处理
                editor.edit(editorEdit => {
                    // 这里可以做以下操作: 删除, 插入, 替换, 设置换行符
                    // 以插入字符串为例: "Hello Word\r\n"
                    // editorEdit.insert(new vscode.Position(0, 0), "Hello Word\r\n");
                }).then(isSuccess => {
                    if (isSuccess) {
                        // console.log("Edit successed");
                    } else {
                        // console.log("Edit failed");
                    }
                }, err => {
                    console.error("Edit error, " + err);
                });
            });
        }).then(undefined, err => {
            console.error(err);
        });
    }  
}

